package jxau.jwgl.api;

import jxau.jwgl.commons.JWGLUserAgent;
import jxau.jwgl.utils.JsonUtil;
import jxau.jwgl.utils.net.OkHttpBuilder;
import jxau.jwgl.utils.net.RetrofitBuilder;
import lombok.NonNull;
import lombok.Setter;
import okhttp3.OkHttpClient;
import retrofit2.Converter;
import retrofit2.Retrofit;
import retrofit2.converter.jackson.JacksonConverterFactory;

import java.util.Objects;
import java.util.concurrent.ConcurrentHashMap;
import java.util.concurrent.ConcurrentMap;

/**
 * WebApiFactory
 *
 * @author LongShu 2017/04/30
 */
public class WebApiFactory {
    private static final ConcurrentMap<String, Object> apiCache = new ConcurrentHashMap<>(8);

    @Setter
    @NonNull
    private static Converter.Factory jsonConverterFactory = null;


    public static Converter.Factory getJsonConverterFactory() {
        if (jsonConverterFactory == null) {
            synchronized (WebApiFactory.class) {
                jsonConverterFactory = JacksonConverterFactory.create(JsonUtil.getObjectMapper());
            }
        }
        return jsonConverterFactory;
    }

    public static Retrofit.Builder getBuilder() {
        OkHttpClient httpClient = new OkHttpBuilder()
                .setAgentInterceptor(JWGLUserAgent.me())
                .builder(true).build();

        Retrofit.Builder builder = new RetrofitBuilder(JWGLServerApiConfig.BASEURL)
                .builder(httpClient)
                .addConverterFactory(getJsonConverterFactory());

        return builder;
    }

    @SuppressWarnings("unchecked")
    public static <T> T get(Class<T> webApi) {
        Objects.requireNonNull(webApi, "webApi is null");
        HttpServiceApi annotation = webApi.getAnnotation(HttpServiceApi.class);
        if (annotation == null) {
            throw new IllegalArgumentException(webApi.getName() + " is not HttpServiceApi.");
        }
        T api = (T) apiCache.get(webApi.getName());

        if (null == api) {
            api = RetrofitBuilder.create(getBuilder(), webApi);
            if (api != null) {
                apiCache.put(webApi.getName(), api);
            }
        }

        return api;
    }

}
